<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>01_v-model的基本使用</title>
  <!-- 
  在 Vue 3 中， `v-model`  是用于在表单元素和 Vue 实例之间创建双向数据绑定的指令。它简化了表单元素的值与 Vue 数据的同步。以下是对  `v-model`  的基本使用说明总结：
  1. 基本用法
  `v-model`  可以用于多种表单元素，如  `<input>` 、 `<textarea>`  和  `<select>` 。基本语法如下：
  <template>
    <div>
      <input v-model="message" placeholder="请输入消息" />
      <p>你输入的消息是: {{ message }}</p>
    </div>
  </template>

  <script>
  export default {
    data() {
      return {
        message: '',
      };
    },
  };
  </script>
  在这个例子中， `v-model`  将输入框的值与  `message`  数据属性进行绑定。当用户在输入框中输入内容时， `message`  的值会自动更新，反之亦然。

  2. 适用场景
  - 文本输入：用于  `<input>`  和  `<textarea>`  元素，方便用户输入文本。
  - 选择框：用于  `<select>`  元素，方便用户选择选项。
  - 复选框和单选框：可以用于复选框和单选框，支持多个值的绑定。

  3. 复合组件的 v-model
  在 Vue 3 中， `v-model`  还可以用于自定义组件。你可以在自定义组件中使用  `v-model`  来实现双向绑定。自定义组件需要使用  `modelValue`  作为 prop，并在事件中发出  `update:modelValue`  事件。
  示例：自定义组件
  <template>
    <div>
      <my-input v-model="inputValue" />
      <p>输入的值是: {{ inputValue }}</p>
    </div>
  </template>

  <script>
  import MyInput from './MyInput.vue';

  export default {
    components: {
      MyInput,
    },
    data() {
      return {
        inputValue: '',
      };
    },
  };
  </script>

  MyInput.vue
  <template>
    <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
  </template>

  <script>
  export default {
    props: {
      modelValue: String,
    },
  };
  </script>

  4. 修饰符
  `v-model`  支持一些修饰符，可以进一步控制其行为：

  -  `.lazy` ：在  `change`  事件时更新，而不是在  `input`  事件时更新。
  -  `.number` ：将输入的值自动转换为数字类型。
  -  `.trim` ：自动去除输入值的前后空格。

  示例：
  <input v-model.lazy="message" placeholder="输入后点击其他地方" />
  <input v-model.number="age" placeholder="请输入年龄" />
  <input v-model.trim="name" placeholder="请输入姓名" />
  
  5. 总结
  -  `v-model` ：用于创建双向数据绑定，简化表单元素与 Vue 实例数据的同步。
  - 适用场景：文本输入、选择框、复选框和单选框等。
  - 复合组件：支持在自定义组件中使用  `v-model` ，通过  `modelValue`  和  `update:modelValue`  事件实现双向绑定。
  - 修饰符：支持  `.lazy` 、 `.number`  和  `.trim`  等修饰符，增强功能。
  -->
</head>
<body>

  <div id="app">
    <h3>1. 登录功能</h3>
    <label for="account">账号：</label>
    <input type="text" id="account" v-model="userInfo.account" />
    <br />
    <label for="password">密码：</label>
    <input type="password" id="password" v-model="userInfo.password" />
    <br />

    <h3>2. textarea</h3>
    <textarea cols="30" rows="10" v-model="userInfo.content"></textarea>

    <h3>3. 单选框</h3>
    <label for="male">男</label>
    <input type="radio" id="male" value="male" v-model="userInfo.gender" />
    <label for="female">女</label>
    <input type="radio" id="female" value="female" v-model="userInfo.gender" />

    <h3>4. 复选框</h3>
    <label for="hobby1">篮球</label>
    <input type="checkbox" id="hobby1" value="篮球" v-model="userInfo.hobbies" />
    <label for="hobby2">足球</label>
    <input type="checkbox" id="hobby2" value="足球" v-model="userInfo.hobbies" />
    <label for="hobby3">羽毛球</label>
    <input type="checkbox" id="hobby3" value="羽毛球" v-model="userInfo.hobbies" />
    <label for="hobby4">乒乓球</label>
    <input type="checkbox" id="hobby4" value="乒乓球" v-model="userInfo.hobbies" />
    <h2>爱好: {{ userInfo.hobbies }}</h2>

    <h3>5. 下拉框</h3>
    <select name="city" multiple size="3" v-model="userInfo.city">
      <option value="beijing">北京</option>
      <option value="shanghai">上海</option>
      <option value="guangzhou">广州</option>
    </select>
    <h2>城市: {{ userInfo.city }}</h2>

    <div>
      <button @click="submit">提交</button>
    </div>
  </div>

  <script src="../lib/vue.js"></script>
  <script>

    const { createApp, ref, reactive } = Vue

    createApp({
      setup() {
        const userInfo = reactive({
          account: '',
          password: '',
          content: '',
          gender: 'male',
          hobbies: [],
          city: 'beijing',
        })

        const submit = () => {
          console.log(userInfo)
        }

        return {
          userInfo,
          submit
        }
      }
    }).mount('#app')

  </script>

  
</body>
</html>